/**
 * 写一个创建方块的抽象类
 * 抽象类的方法传入三个参数
 * x为绝对定位left值
 * y为绝对定位top值
 * color为方块的背景色
 * createRect方法为该对象原型上
 * 创建方块的方法
 */
function Rect(x, y, color,type) {
	this.x = x;
	this.y = y;
	this.color = color;
    this.type = type; 
	this.createRect();
}
/**
 * 在方块对象原型上定义一个创造方块的方法
 * 对象原型方法中创建一个div元素，名为rectEle
 * 该宽度为10px
 * 该高度为10px
 * 该元素定位属性为绝对定位
 * 该元素定位的left值为传入的x
 * 该元素定位的top值为传入的y
 * 该元素的背景色为传入的color
 * 该元素的border边框1px solid
 */
Rect.prototype.createRect = function () {
	this.rectEle = document.createElement("div");
	this.rectEle.style.width = "10px";
	this.rectEle.style.height = "10px";
	this.rectEle.style.position = "absolute";
	this.rectEle.style.left = this.x + "px";
	this.rectEle.style.top = this.y + "px";
	this.rectEle.style.boxSizing = "border-box";
	this.rectEle.style.background = this.color;
	this.rectEle.style.border = "1px solid";
};

let containerEle = document.querySelector(".container");
/**
 * 创建一个实物类
 * 
*/

function Food (containerEle){
    this.containerEle = containerEle ; 
    
}
Food.prototype.createFood = function (){
    let x = getRandom( parseInt(getStyle(containerEle, "width")) / 10 - 1,0) * 10 ;
    let y = getRandom( parseInt(getStyle(containerEle, "height")) / 10 - 1,0) * 10 ;
    let rect = new Rect( x , y , "yellow" , 'food');
    this.rect = rect ;
    rect.rectEle.style.boxSizing = "border-box";
	this.containerEle.appendChild(rect.rectEle);
}

let food = new Food(containerEle);

/**
 * 写一个蛇类的方法，该方法需要传入一个承载蛇的界面元素
 * 给蛇对象一个蛇身数组
 * 执行蛇对象创建蛇身的方法
 * 执行蛇对象渲染界面的方法
 *
 */
function Snake(containerEle) {
	this.containerEle = containerEle;
	this.body = [];
	this.createBody();
	this.renderDom();
    this.snakeMove();
}

/**
 * 在蛇类的原型对象上写一个创建身体的方法createBody
 * 蛇长度为5
 * 身体为绿色，长度为4
 * 蛇头为红色，长度为1
 * 将每一个蛇身模块实例化
 * 并放入到蛇身数组中
 *
 */
Snake.prototype.createBody = function () {
	for (let i = 0; i < 5; i++) {
		let rect;
		if (i == 4) {
			rect = new Rect(i * 10, 0, "red",'head');
		} else {
			rect = new Rect(i * 10, 0, "blue",'body');
		}
		this.body.push(rect);
	}
};

/**
 * 在蛇类的原型上创建一个渲染的方法
 * 遍历蛇对象的蛇身数组
 * 将数组中每一个div元素放到containerEle元素中
 */
Snake.prototype.renderDom = function () {
	this.body.forEach((rect) => {
		this.containerEle.appendChild(rect.rectEle);
	});
};

Snake.prototype.snakeMove = function (){
    let that = this ; 
    let speed = 10;
    
    let direction = "left";
    document.onkeydown = function (event) {
        var e = event || window.event;
        var key = e.key;

        if (key == "ArrowUp") {
            direction = "top";
            speed = -Math.abs(speed);
        }
        if (key == "ArrowDown") {
            direction = "top";
            speed = Math.abs(speed);
        }
        if (key == "ArrowLeft") {
            direction = "left";
            speed = -Math.abs(speed);
        }
        if (key == "ArrowRight") {
            direction = "left";
            speed = Math.abs(speed);
        }
        that.direction = direction ; 
        that.speed = speed ; 
    };
    this.direction = direction ; 
    this.speed = speed ; 
    food.createFood();
    let num = timer( that , 300 );
        
}
function timer ( that , delay ){
    let timer = setInterval(function () {
        console.log(that.speed);
        that.body.forEach((rect,key,arr) => {
            if ( rect.type == 'head' ){
                console.log(that);
                rect.rectEle.style[that.direction] = parseInt( rect.rectEle.style[that.direction] ) + that.speed +'px';
                let xx = parseInt( rect.rectEle.style.left ) ; 
                let yy = parseInt( rect.rectEle.style.top ) ;
                let y = parseInt( food.rect.rectEle.style.top ) ; 
                let x = parseInt( food.rect.rectEle.style.left ) ;
               
                if ( xx < 0 || xx > that.containerEle.clientWidth - parseInt(rect.rectEle.style.width) 
                || yy < 0 || yy > that.containerEle.clientHeight - parseInt(rect.rectEle.style.height) ){
                    clearTimeout(timer);
                    window.alert("你死了");
                }   
                arr.forEach((item,key)=>{
                    if( item.type == 'body' )
                    {
                        let xBody = parseInt( item.rectEle.style.left );
                        let yBody = parseInt( item.rectEle.style.top );
                       
                        if ( crash( xx , yy , xBody , yBody ) ){
                            clearTimeout(timer);
                            window.alert("你死了");
                        }
                    }
                });
                if ( crash( xx , yy , x , y ) ) {
                    food.rect.rectEle.style.display = 'none' ;
                    let rect = new Rect(-10,0,"blue","body");
                    snake.body.unshift(rect);
                    snake.renderDom();
                    food.createFood();
                }
            } else {
                rect.rectEle.style.top = arr[key+1].rectEle.style.top ; 
                rect.rectEle.style.left = arr[key+1].rectEle.style.left ;
            }
        });
    }, delay);
}

// 获取containerEle元素
// 创建一个蛇对象，然后实例化

let snake = new Snake(containerEle);

/**
 * 创建一个渲染界面背景的方法
 * 传入承载背景的元素
 * 调用创建背景的方法
 * */
function Background(containerEle) {
	this.containerEle = containerEle;
	this.createBackground();
}
/**
 * 在Background类的原型对象中写一个创建背景的方法
 * 调用获取非行间样式的函数
 * 获取承载背景元素的宽和高
 * 计算该盒子能放多少行，多少列元素
 * 实例化所有一个方块
 * 把方块的div元素的定位属性移除
 * 给方块的div元素加一个怪异盒子属性
 * 然后将方块的div元素加入到承载这些盒子的元素中
 */
Background.prototype.createBackground =
	function () {
		let x =
			parseInt(getStyle(containerEle, "width")) /
			10;
		let y =
			parseInt(getStyle(containerEle, "height")) /
			10;
		// console.log(x,y);
		for (let i = 0; i < x; i++) {
			for (let j = 0; j < y; j++) {
				let rect = new Rect(
					j * 10,
					i * 10,
					"#ccc",
                    'bGround'
				);
				rect.rectEle.style.position = "static";
				rect.rectEle.style.boxSizing =
					"border-box";
				this.containerEle.appendChild(
					rect.rectEle
				);
			}
		}
	};
/**
 * *
 * 实例化一个Background类的对象
 *
 */
let background = new Background(containerEle);



// food.createFood();

function getRandom(max,min){
    return parseInt( Math.random() * ( max - min + 1 ) + min );
}

function getStyle(ele, styleName) {
	if (window.getComputedStyle) {
		return getComputedStyle(ele, null)[styleName];
	} else {
		return ele.currentStyle[styleName];
	}
}

function crash( xx , yy , x , y ){
    if ( xx == x && yy ==y ){
        return true ; 
    } else {
        return false ;
    }
}